﻿module StochasticSimulation.PriorityQueues.Tests

open NUnit.Framework
open System
open StochasticSimulation.ChemicalReaction.PriorityQueue
open StochasticSimulation.ChemicalReaction.ChemicalReaction
open StochasticSimulation.ChemicalReaction.ChemicalSpecies


let isInfinite nt =
    match nt with
        | Normal(t)    -> false
        | Infinite(_)  -> true
        
[<TestFixture>] 
type ``Given a queue of reactions`` ()= class

    [<TestCase(0, true)>]
    [<TestCase(1, false)>]
    [<Test>] 
    member test.`` check that only reactions with zero propensity have infinite time`` ( count, expected )=
        let system = [ {Species = { Name ="I" } ; Count = count };]
        let reactions = [ { Rate = 1.0 ; Changes = dict[ {Name = "I"}, {Destroyed =1 ; Created=0}] };]
        let q = new PriorityQueue(system, reactions)
        let (nextR, nextT) = q.Next
        Assert.AreEqual( isInfinite nextT, expected)


    [<Test>] 
    member test.`` check that updated queue keeps old time when propensity goes to infinity`` ( )=
        let system = [ {Species = { Name ="I" } ; Count = 1 }]
        let r =  { Rate = 1.0 ; Changes = dict[ {Name = "I"}, {Destroyed =1 ; Created=0}] }

        let reactions = [r]
        let startTime = 2.2

        let q = new PriorityQueue(system, reactions, startTime)
        let (nextR, nextT) = q.Next

        Assert.False(  isInfinite nextT )

        let infinityTime = 3.3

        q.Update( [ (r, Infinite(infinityTime) ) ] )

        Assert.True ( isInfinite (snd q.Next) )

        q.Update( [ (r, Normal(infinityTime)) ] )

        let oldTime nt = 
            match nt with
                | Normal(t) -> t
                | Infinite(o) -> o
        Assert.AreEqual( oldTime (snd q.Next), infinityTime )

end